//
//  UIImage+Extension.m
//  TotalDemo
//
//  Created by gujian on 16/6/24.
//  Copyright © 2016年 gujian. All rights reserved.
//

#import "UIImage+Extension.h"

CGFloat DegreeToRadians (CGFloat degree) {return degree * M_PI / 180; }

@implementation UIImage (Extension)



/** 翻转图片 */

- (UIImage *)rotateImageWithorientation:(UIImageOrientation)orientation
{
    
    
    if (self.imageOrientation != UIImageOrientationUp) {
        LotLog(@"原始图像方向：%@",@(self.imageOrientation));
        return self;
    }
    

    switch (orientation) {
        case UIImageOrientationUp:
//            return [self rotateImageToRadians:0];
            return [self rotateImageViaRadians:0];
            break;
        case UIImageOrientationDown:{
//            return [self rotateImageToRadians:M_PI];
            return [self rotateImageViaRadians:M_PI/3.0];
        }
            break;
        case UIImageOrientationLeft:
//            return [self imageWithRadian:-M_PI_2];
            return [self rotateImageViaRadians:-M_PI_2];
            break;
        case UIImageOrientationRight:
//            return [self imageWithRadian:M_PI_2];
            return [self rotateImageViaRadians:M_PI_2];
            break;
        case UIImageOrientationUpMirrored:
            return [self rotateImageToRadians:0 isMirrored:YES];
            break;
        case UIImageOrientationDownMirrored:
            return [self rotateImageToRadians:M_PI isMirrored:YES];
            break;
        case UIImageOrientationLeftMirrored:
            return [self rotateImageToRadians:-M_PI_2 isMirrored:YES];
            break;
        case UIImageOrientationRightMirrored:
            return [self rotateImageToRadians:M_PI_2 isMirrored:YES];
            break;
            
    }
    
    
    UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    
    return targetImage;
}

- (UIImage *)imageWithRadian:(CGFloat)radians
{
    CGSize imgSize = self.size;
    CGFloat scale = [UIScreen mainScreen].scale;
    imgSize.width *= scale;
    imgSize.height *= scale;
    
    UIGraphicsBeginImageContextWithOptions(imgSize, NO, 0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSaveGState(context);

    //移动坐标系与用户坐标系相同 防止镜像
    CGContextTranslateCTM(context, 0, imgSize.height);
    //设置翻转正向
    CGContextScaleCTM(context, 1.0, -1.0);
    
    //旋转
    CGContextRotateCTM(context, radians);
    
    //采用中心点作为初始点
    CGFloat currentX = imgSize.width/2.0;
    CGFloat currentY = imgSize.height/2.0;
    
    //坐标系旋转变换
    CGFloat targetX = currentX * cos(radians) + currentY * sin(radians);
    CGFloat targetY = currentY * cos(radians) - currentX * sin(radians);
    
    //计算偏移量
    CGFloat offX = targetX - currentX;
    CGFloat offY = targetY - currentY;
    
    NSLog(@"offX:%@",@(offX));
    NSLog(@"offY:%@",@(offY));
    

    CGContextTranslateCTM(context, offX, offY);
    
    CGContextDrawImage(context, CGRectMake(0, 0, imgSize.width, imgSize.height), [self CGImage]);
    
    UIImage *targetImage = UIGraphicsGetImageFromCurrentImageContext();
    
    CGContextRestoreGState(context);
    
    
    return targetImage;
    
}

- (UIImage *)rotateImageViaRadians:(CGFloat)radians
{
    CGSize imgSize = self.size;
    imgSize.width *= self.scale;
    imgSize.height *= self.scale;
    
    
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    CGFloat currentX = imgSize.width/2.0;
    CGFloat currentY = imgSize.height/2.0;
    
    radians = M_PI - radians;
    
    //坐标系旋转后的新坐标
    CGFloat targetX = currentX * cos(radians) + currentY * sin(radians);
    CGFloat targetY = currentY * cos(radians) - currentX * sin(radians);
    
    CGFloat offX = targetX - currentX;
    CGFloat offY = targetY - currentY;
    
    
    CGRect targetRect = CGRectMake(0, 0, imgSize.width, imgSize.height);
    targetRect = CGRectApplyAffineTransform(targetRect, CGAffineTransformMakeRotation(radians));
    CGSize outputSize = CGSizeMake(CGRectGetWidth(targetRect), CGRectGetHeight(targetRect));
    
    CGFloat deltaWidth = outputSize.width - imgSize.width;
    CGFloat deltaHeight = outputSize.height - imgSize.height;
    
    
    //矩阵变换时，后面的矩阵先作用，前面的矩阵后作用
    //为什么要交换 offX offY？ 以及为什么公式是这样的
    transform = CGAffineTransformTranslate(transform, -offY+deltaWidth/2.0, -offX+deltaHeight/2.0);
    transform = CGAffineTransformRotate(transform, radians);
    

    
    CGContextRef context = CGBitmapContextCreate(NULL,outputSize.width, outputSize.height, CGImageGetBitsPerComponent(self.CGImage),0,CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(context, transform);
    
    CGContextDrawImage(context, CGRectMake(0, 0, imgSize.width, imgSize.height), self.CGImage);
    
    CGImageRef cgimage = CGBitmapContextCreateImage(context);
    
    UIImage *targetImage = [UIImage imageWithCGImage:cgimage];
    
    CGContextRelease(context);
    CGImageRelease(cgimage);
    
    
    return targetImage;
}


- (UIImage *)rotateImageToRadians:(CGFloat)radians
{
    
    return [self rotateImageToRadians:radians isMirrored:NO];
}

- (UIImage *)rotateImageToRadians:(CGFloat)radians isMirrored:(BOOL)isMirrored
{
    if (isMirrored) {
        //Core Graphics中图像为倒置模式 需先将图形旋转M_PI
        radians = M_PI - radians;
    }
    
    CGSize imgSize = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale);
    CGSize outputSize = imgSize;
    
    //设置画布大小，保留图像旋转后没有被裁剪
    CGRect rect = CGRectMake(0, 0, imgSize.width, imgSize.height);
    rect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeRotation(radians));
    outputSize = CGSizeMake(CGRectGetWidth(rect), CGRectGetHeight(rect));
    
    UIGraphicsBeginImageContextWithOptions(outputSize, NO, 0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSaveGState(context);
    
    CGContextTranslateCTM(context, outputSize.width/2.0, outputSize.height/2.0);
    CGContextRotateCTM(context, radians);
    CGContextTranslateCTM(context, -imgSize.width/2.0, -imgSize.height/2.0);
    
    
    if (isMirrored) {
        /** 
         *此处的rect遵守的是 user space 坐标系，图像渲染出来后会发生镜像问题
         
         */
        CGContextDrawImage(context, CGRectMake(0, 0, imgSize.width, imgSize.height), [self CGImage]);
    }else
    {
        /**
         *此处的rect遵守的是Core Graphics坐标系，所以没有发生渲染出来的图像为镜像的问题
         *方法自动处理镜像问题
         
         */
        [self drawInRect:CGRectMake(0, 0, imgSize.width, imgSize.height)];
    }
    
    
    UIImage *resuleImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    
    CGContextRestoreGState(context);
    
    
    return resuleImage;
    
}



@end
